package cn.org.xuanguang.kepler.hormos.spring.starter;

import cn.org.xuanguang.kepler.hormos.orm.acl.IPolicyInterceptorChain;
import cn.org.xuanguang.kepler.hormos.orm.acl.impl.KeplerTenantPolicy;
import cn.org.xuanguang.kepler.hormos.rdb.executor.JdbcSyncSqlExecutor;
import cn.org.xuanguang.kepler.hormos.rdb.executor.SyncSqlExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;
import java.sql.SQLException;

@EnableConfigurationProperties(value = HormosOptions.class)
public class HormosAutoConfiguration {

    @Autowired
    private DataSource dataSource;

    /**
     * 创建并返回一个HormosManager实例。
     * 这个方法使用HormosOptions和dataSource来初始化HormosManager。
     *
     * @param hormosOptions Hormos框架的配置选项，用于配置HormosManager的行为。
     * @return HormosManager的实例，用于管理Hormos框架的操作。
     * @throws SQLException 如果在初始化HormosManager时遇到数据库相关错误，则抛出SQLException。
     */
    @Bean
    @ConditionalOnMissingBean(HormosManager.class)//不存在HormosManager时初始化该配置类
    public HormosManager hormosManager(HormosOptions hormosOptions) throws SQLException {
        // 使用提供的HormosOptions和dataSource实例化HormosManager
        // 添加注册数据源
        HormosDataSourceManager.addDataSource(hormosOptions.getDsId(), dataSource);
        return new HormosManager(hormosOptions);
    }


    /**
     * 默认数据源的执行器
     * 创建并返回一个 SyncSqlExecutor 实例，具体实现为 JdbcSyncSqlExecutor。
     * 此方法只有在当前应用中不存在任何 JdbcSyncSqlExecutor 类型的 Bean 时才会被调用，
     * 通过 @ConditionalOnMissingBean 注解实现了条件加载。
     *
     * @param hormosOptions 包含 Hromos 相关配置信息的对象，主要用于指定数据库方言。
     * @return 返回一个配置好的 SyncSqlExecutor 实例，用于执行同步 SQL 任务。
     * @throws SQLException 如果在初始化过程中遇到任何数据库相关错误，则抛出 SQLException。
     */
    @Bean
    @ConditionalOnMissingBean(SyncSqlExecutor.class)
    public SyncSqlExecutor syncSqlExecutor(HormosOptions hormosOptions) throws SQLException {
        return new JdbcSyncSqlExecutor(dataSource, hormosOptions.getDialect());
    }

    @Bean
    @ConditionalOnMissingBean(IPolicyInterceptorChain.class)
    public IPolicyInterceptorChain policyInterceptorChain(HormosOptions hormosOptions) throws SQLException {
        // 默认不加载拦截器，如果需要加载拦截器，请配置参数
        IPolicyInterceptorChain iPolicyInterceptorChain = new IPolicyInterceptorChain();
        if (hormosOptions.getMultiTenant().getEnable()) {
            iPolicyInterceptorChain.addInterceptor(new KeplerTenantPolicy(hormosOptions.getMultiTenant()));
        }
        return iPolicyInterceptorChain;
    }

}